﻿// Jeremy Lee
// Battle Tactics- A turn based strategy game
// Unit.cs- A class representing the Unit
using System;
using System.Collections.Generic;
using System.Linq;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Audio;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.GamerServices;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
using Microsoft.Xna.Framework.Media;

namespace BattleTactics
{
    public class Unit
    {
        public UnitState state;
        public int[] stats; // 8 attributes
        public Texture2D sprite;
        public string spritePath;
        public VectorInt loc;
        public bool alive;
        public int owner;
        protected Color tint;
        protected int frameCount;
        protected int frameTimer;
        public Rectangle[] frameRect;
        public int[][] animateSeq;
        public bool[] actions;

        public Unit()
        {
            state = UnitState.END;
            stats = new int[] { 0, 0, 0, 0, 0, 0, 0, 0 };
            sprite = null;
            spritePath = "null";
            loc = new VectorInt(0);
            alive = false;
            owner = -1;
            tint = Color.White;
            frameCount = 0;
            frameTimer = 200;
            frameRect = new Rectangle[] { new Rectangle(0, 0, 0, 0) };
            animateSeq = new int[][] { new int[] { 0 } };
            actions = new bool[] { false, false, false };
        }
        public Unit(string path, int[] stat, int own)
        {
            state = UnitState.READY;
            spritePath = path;
            sprite = Globl.content.Load<Texture2D>(path);
            stats = new int[stat.Length];
            Array.Copy(stat, stats, stat.Length);
            loc = new VectorInt(0);
            alive = false;
            owner = own;
            tint = Color.White;
            frameCount = 0;
            frameTimer = 200;
            frameRect = new Rectangle[] { new Rectangle(0, 0, sprite.Width, sprite.Height) };
            animateSeq = new int[][] { new int[] { 0 } };
            actions = new bool[] { false, false, false };
        }

        public void updateFrame(int elapsedTime)
        {
            if (state == UnitState.END)
                tint = Color.Gray;
            else
                tint = Color.White;

            int tmpState = (int)state;
            if (tmpState > 2)
                tmpState = 0;
            
            frameTimer -= elapsedTime;
            if (frameTimer <= 0)
            {
                frameCount = (frameCount + 1) % animateSeq[tmpState].Length;
                frameTimer += 200;
            }                
        }

        public void draw(SpriteBatch sb, VectorInt pos )
        {
            int tmpState = (int)state;
            if (tmpState > 2)
                tmpState = 0;
            sb.Draw(sprite,
                     new Rectangle(pos.X * Globl.TILE_SIZE,
                                    pos.Y * Globl.TILE_SIZE,
                                    Globl.TILE_SIZE,
                                    Globl.TILE_SIZE),
                     frameRect[animateSeq[tmpState][frameCount]],
                     tint, 0.0f, Vector2.Zero, SpriteEffects.None,
                     0.25f);
        }

        public void attack(Unit target)
        {
            int tmp = this.stats[(int)Stats.ATK] - target.stats[(int)Stats.DEF];
            if (tmp < 0)
                tmp = 0;
            target.stats[(int)Stats.HP] -= tmp;
            tmp = target.stats[(int)Stats.LVL] - this.stats[(int)Stats.LVL];
            if( tmp < -10 )
                tmp = -10;
            this.stats[(int)Stats.EXP] += 10 + tmp;
            target.stats[(int)Stats.EXP]++;
            if (target.stats[(int)Stats.HP] <= 0)
            {
                target.alive = false;
                this.stats[(int)Stats.EXP] += (30 + 3 * tmp);
            }
            if (this.stats[(int)Stats.EXP] >= 100)
                this.LevelUp();
            if (target.stats[(int)Stats.EXP] >= 100)
                target.LevelUp();
        }

        public void LevelUp()
        {
            stats[(int)Stats.EXP] -= 100;
            stats[(int)Stats.HPMAX] += Globl.rand.Next(2, 4);
            int tmp = Globl.rand.Next(100);
            if( tmp < 75 )
                stats[(int)Stats.ATK]++;
            tmp = Globl.rand.Next(100);
            if( tmp < 60 )
                stats[(int)Stats.DEF]++;
            stats[(int)Stats.LVL]++;
        }
    }
}
